#ifndef VOLUMEMASK_H
#define VOLUMEMASK_H

#include <GL/glew.h>
#include <QGLViewer/vec.h>
using namespace qglviewer;

#include <QBitArray>

#include "volumefilemanager.h"

class VolumeMask
{
 public :
  VolumeMask();
  ~VolumeMask();

  void setDimensions(int, int, int);
  void setSubsamplingLevel(int);

  void updateBitmask(int,
		     int, int, int,
		     int, int, int,
		     QBitArray,
		     int, int, int,
		     int, int, int,
		     int, int, int,
		     int);

  void tagVolumeWithUpdateMask(int,
			       QList<Vec>,
			       QList<Vec>,
			       int, int, int,
			       int, int, int,
			       QBitArray,
			       int, int, int,
			       int, int, int,
			       int, int, int,
			       int,
			       QList<Vec>,
			       QList<Vec>);

  void fillVolumeWithUpdateMask(int,
				QList<Vec>,
				int,
				int, int, int,
				int, int, int,
				QBitArray,
				int, int, int,
				int, int, int,
				int, int, int,
				int,
				QList<Vec>,
				QList<Vec>);
  
  void tagVolume(int, bool,
		 unsigned char*,
		 int, int,
		 int, int,
		 int, unsigned char*,
		 QList<Vec>,
		 QList<Vec>);


  void tagVolume(int, bool,
		 Vec, Vec,
		 unsigned char*,
		 int, int,
		 int, int,
		 int, unsigned char*,
		 QList<Vec>,
		 QList<Vec>);


  void tagUsingBitmask(int, bool,
		       unsigned char*,
		       int, int,
		       int, int,
		       int, unsigned char*,
		       QBitArray,
		       int,
		       int, int, int,
		       QList<Vec>,
		       QList<Vec>);

  void dilateVolume(int, int,
		    int, int, int,
		    int, int, int,
		    QBitArray,
		    QList<Vec>,
		    QList<Vec>);
    
  void erodeVolume(int, int,
		   int, int, int,
		   int, int, int,
		   QBitArray,
		   QList<Vec>,
		   QList<Vec>);
    
  void dilateAllVolume(int, int,
		       int, int, int,
		       int, int, int,
		       QBitArray,
		       QList<Vec>,
		       QList<Vec>);
    
  void erodeAllVolume(int, int,
		      int, int, int,
		      int, int, int,
		      QBitArray,
		      QList<Vec>,
		      QList<Vec>);
    
  int getVolume(unsigned char,
		int, int, int,
		int, int, int,
		QBitArray&);
  
  void setFilename(QString);
  void setDragTextureSize(Vec, int, int);
  void setDataSize(Vec, Vec);
  void resetSliceTexture(int, int, int, int, int, int, int);

  uchar* getSliceTextureSlab(int, int);
  uchar* getDragTexture();

 private :
  VolumeFileManager m_maskFileManager;
  QString m_maskFilename;
  int m_width, m_height, m_depth;
  uchar* m_sliceTexture;
  uchar* m_dragTexture;
  uchar* m_sliceTemp;
  Vec m_dragTextureSize;
  int m_dragTexWidth, m_dragTexHeight;
  Vec m_dataMin, m_dataMax;
  Vec m_subvolumeSize;
  int m_texColumns, m_texRows;
  int m_texWidth, m_texHeight;
  int m_slabSize;
  int m_svsl;

  QBitArray m_bitmask;

  void createBitmask(int,
		     int, int, int,
		     int, int, int);

  void dilateBitmask(int, int, int,
		     int, int, int);

  void erodeBitmask(int, int, int,
		    int, int, int);
  
  void destroyBitmask();


  void createBitmask1(QList<Vec>,
		      QList<Vec>,
		      QBitArray,
		      int, int, int,
		      int, int, int);

  void createBitmask2(QList<Vec>,
		      int,
		      int, int, int,
		      int, int, int);

  void tagAndUpdateBitmask(int,
			   int, int, int,
			   int, int, int,
			   QBitArray,
			   int, int, int,
			   int, int, int,
			   int, int, int,
			   int,
			   QList<Vec>,
			   QList<Vec>);
  bool getOpacity(uchar*,
		  uchar*,
		  uchar*,
		  uchar*,
		  int, int);

  bool getOpacity(uchar*,
		  uchar*,
		  int, int);
};

#endif
